package org.msfj.authority.server.service.impl;

import cn.hutool.core.util.ObjectUtil;
import org.msfj.admin.feign.UserApi;
import org.msfj.admin.vo.UserVo;
import org.msfj.authority.client.config.JwtConfig;
import org.msfj.authority.server.service.UserAuthService;
import org.msfj.authority.server.util.UserJwtTokenUtil;
import org.msfj.common.annotation.Constants;
import org.msfj.common.model.CommonResult;
import org.msfj.common.util.jwt.IJWTInfo;
import org.msfj.common.util.jwt.JWTInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import java.util.concurrent.TimeUnit;

@Service
public class UserAuthServiceImpl implements UserAuthService {

    Logger logger = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private UserJwtTokenUtil userJwtTokenUtil;

    private BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(Constants.PW_ENCORDER_SALT);

    @Autowired
    private UserApi userApi;

    @Autowired
    JwtConfig jwtConfig;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;


    @Override
    public String login(String account, String password) {
        String token = null;
        try {
            CommonResult<UserVo> result = userApi.getByAccount(account);
            if (result != null && result.isOK()) {
                UserVo userVo = result.getData();
                if (userVo != null) {
                    //新密码验证
                    if (encoder.matches(password, userVo.getPassword())) {
                        token = userJwtTokenUtil.generateToken(new JWTInfo(userVo.getAccount(), userVo.getId() + "", userVo.getName()));
                    } else { //尝试旧密码验证
                        logger.error("用户密码不匹配，数据库的密码是：" + userVo.getPassword());
                    }
                } else {
                    logger.error("用户(" + account + ")不存在");
                }
            } else {
                logger.error("查询用户信息出错：", result.getMsg());
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("登录出错", e);
        }
        return token;
    }

    @Override
    public Boolean invalid(String token) throws Exception {
        IJWTInfo infoFromToken = null;
        try {
            infoFromToken = userJwtTokenUtil.getInfoFromToken(token);
            redisTemplate.opsForValue().set(infoFromToken.getUniqueName(), token);
            redisTemplate.expire(infoFromToken.getUniqueName(), infoFromToken.getBuffer(), TimeUnit.SECONDS);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("解析 token错误", e);
            return false;
        }
    }

    @Override
    public String refresh(String oldToken) throws Exception {
        String token = oldToken;
        IJWTInfo infoFromToken = userJwtTokenUtil.getInfoFromToken(oldToken);
        String username = infoFromToken.getUniqueName();
        if (username == null) {
            return null;
        } else {
            if (infoFromToken.getBuffer() <= jwtConfig.getUserBuffer()) {
                CommonResult<UserVo> result = userApi.getByAccount(username);
                if (ObjectUtil.isNotNull(result)) {
                    UserVo userVo = result.getData();
                    token = userJwtTokenUtil.generateToken(new JWTInfo(userVo.getAccount(), userVo.getId() + "", userVo.getName()));
                }
            }
        }
        return token;
    }
}
